package nimy.info.android.dinnertime.page;

import info.nimy.google.recipesearch.html.RecipeItem;

import java.util.List;

import nimy.info.android.dinnertime.Constants;
import nimy.info.android.dinnertime.HomeActivity;
import nimy.info.android.dinnertime.R;
import nimy.info.android.dinnertime.adapter.RecipeItemAdapter;
import nimy.info.android.dinnertime.connectivity.LoaderState;
import nimy.info.android.dinnertime.data.MemoryRecipeItemCache;
import nimy.info.android.dinnertime.data.RecipeItemCache;
import nimy.info.android.dinnertime.model.RecipeKeyword;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.support.v4.widget.SearchViewCompat;
import android.support.v4.widget.SearchViewCompat.OnQueryTextListenerCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;

import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.MenuItem.OnMenuItemClickListener;
import com.markupartist.android.widget.PullToRefreshListView;
import com.markupartist.android.widget.PullToRefreshListView.OnRefreshListener;

/**
 * 
 * @author 234aini@gmail.com 2012-10-29
 * 
 */
public class RecipeListPage extends AbstractSinglePage implements
		LoaderCallbacks<LoaderState<List<RecipeItem>>> {
	public static final String TAG = RecipeListPage.class.getName();
	private PullToRefreshListView mListView;
	private RecipeItemAdapter mRecipeListAdapter;

	private RecipeKeyword mRecipeKeyword;
	private RecipeItemCache mRecipeItemCache;

	private RecipeItemLoader mLoader;
	private Bundle mSavedInstanceState;

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		this.mSavedInstanceState = savedInstanceState;
		loadLocalCachedRecipes();
		getLoaderManager().initLoader(Constants.LOADER_RECIPE_LIST,
				savedInstanceState, this);
		setHasOptionsMenu(true);
	}

	private void loadLocalCachedRecipes() {
		// TODO maybe we can save the data into local SDCARD and then load it
		// again
		if (mRecipeItemCache == null)
			mRecipeItemCache = new MemoryRecipeItemCache();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		/**
		 * The last parameter false is very important. we can't attach the view
		 * to root
		 */
		View inflate = inflater.inflate(R.layout.recipe_summary_list_page,
				container, false);
		mListView = (PullToRefreshListView) inflate
				.findViewById(R.id.recipe_list_view);
		setupRecipeListView(mListView);
		return inflate;
	}

	private void setupRecipeListView(final PullToRefreshListView paninationView) {
		mRecipeListAdapter = new RecipeItemAdapter(getContext());
		paninationView.setAdapter(mRecipeListAdapter);
		paninationView.setOnRefreshListener(new OnRefreshListener() {
			@Override
			public void onRefresh() {
				triggerRecipeSearch(false);
			}

		});
		mListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> adapterView, View itemView,
					int position, long itemId) {
				RecipeItem item = (RecipeItem) paninationView
						.getItemAtPosition(position);
				HomeActivity.getApplicaiton().openWebViewForRecipe(item);

				if (HomeActivity.DEBUG) {
					Log.d(TAG, "Select recipe " + item.getName());
				}
			}

		});
	}

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		// Place an action bar item for searching.
		MenuItem item = menu.add("Search");
		item.setIcon(android.R.drawable.ic_menu_search);
		item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
		item.setOnMenuItemClickListener(new OnMenuItemClickListener() {
			@Override
			public boolean onMenuItemClick(MenuItem item) {
				HomeActivity.getApplicaiton().showPage(
						Constants.TAB_RECIPE_KEYWORD);
				return true;
			}
		});
		// does not work on my milestone 2.3.3 version :(
		View searchView = SearchViewCompat.newSearchView(getSherlockActivity());
		if (searchView != null) {
			SearchViewCompat.setOnQueryTextListener(searchView,
					new OnQueryTextListenerCompat() {
						@Override
						public boolean onQueryTextChange(String newText) {
							RecipeKeyword keyword = new RecipeKeyword(newText,
									0);
							search(keyword);
							return true;
						}
					});
			item.setActionView(searchView);
		}
	}

	public Context getContext() {
		return getActivity().getApplicationContext();
	}

	/**
	 * It's public method for other page to call to trigger the search
	 * operation.
	 * 
	 * @param currentKeyword
	 */
	public void search(final RecipeKeyword currentKeyword) {
		if (currentKeyword == null) {
			return; // do nothing if keyword is null
		}
		boolean isKeywordChanged = !currentKeyword.equals(mRecipeKeyword);
		this.mRecipeKeyword = currentKeyword; // save the keyword status
		if (isKeywordChanged) {
			// clear the list view
			mRecipeListAdapter.clear();
			mRecipeListAdapter.addRecipes(mRecipeItemCache
					.getCached(currentKeyword));
			if (mLoader.isStarted()) {
				mLoader.abandon(); // abandon the previous loader
				getLoaderManager().restartLoader(Constants.LOADER_RECIPE_LIST,
						mSavedInstanceState, this);
			}
		}
		mListView.setSelectionAfterHeaderView();
		triggerRecipeSearch(true);
	}

	private void triggerRecipeSearch(boolean prepareRefresh) {
		if (prepareRefresh) {
			// show the loading indicator
			mListView.prepareForRefresh();
		}
		mLoader.pleaseLoad(mRecipeKeyword);
	}

	@Override
	public Loader<LoaderState<List<RecipeItem>>> onCreateLoader(int indicator,
			Bundle bundle) {
		mLoader = new RecipeItemLoader(getSherlockActivity(), bundle);
		mLoader.setCache(mRecipeItemCache);
		return mLoader;
	}

	@Override
	public void onLoadFinished(Loader<LoaderState<List<RecipeItem>>> loader,
			LoaderState<List<RecipeItem>> loaderResult) {
		if (loaderResult.getThrowable() != null && !loader.isAbandoned()) {
			HomeActivity.getApplicaiton().showErrorMessage(
					R.string.error_network_timeout_exception);
		} else {
			mRecipeListAdapter.addRecipes(loaderResult.getData());
		}
		// always make the load progress indicator is completed
		mListView.onRefreshComplete();
	}

	@Override
	public void onLoaderReset(Loader<LoaderState<List<RecipeItem>>> loader) {
		loader.stopLoading();
	}

}
